﻿// -----------------------------------------------------------------------
// <copyright file="Obstacle.cs" company="Diddly Squad">
// </copyright>
// -----------------------------------------------------------------------

using FarseerPhysics.Dynamics;
using FarseerPhysics.Factories;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace DiddlySquat
{

	public class Obstacle
	{
		#region Properties

		public Body ObstacleBody { get; set; }
		public Texture2D ObstacleSprite { get; set; }

		public Vector2 Origin { get; protected set; }

		public Animation ObstacleAnimation { get; protected set; }

		public float Width { get; protected set; }

		public float Height { get; protected set; }

		public Enums.ObstacleType ObstacleType { get; set; }

		public bool Active { get; protected set; }

		#endregion

		/// <summary>
		/// Initializes Obstacle.
		/// </summary>
		/// <param name="world">The world.</param>
		/// <param name="xpos">The xpos.</param>
		/// <param name="ypos">The ypos.</param>
		/// <param name="density">The density.</param>
		/// <param name="rotation">The rotation.</param>
		/// <param name="sprite">The sprite.</param>
		/// <param name="obstacleType">Type of the obstacle.</param>
		public virtual void Initialize(World world, float xpos, float ypos, float density, float rotation, Texture2D sprite, Enums.ObstacleType obstacleType)
		{
			this.ObstacleSprite = sprite;

			this.Height = sprite.Height;
			this.Width = sprite.Width;

			this.Origin = new Vector2(this.ObstacleSprite.Width / 2f, this.ObstacleSprite.Height / 2f);

			//Dimensions are always the same as the sprite's dimensions.
			this.ObstacleBody = BodyFactory.CreateRectangle(world, ((float)this.Width / Constants.MeterInPixels), ((float)this.Height / Constants.MeterInPixels), density, this);

			this.ObstacleBody.BodyType = BodyType.Static;

			this.ObstacleBody.Restitution = 0.3f;
			this.ObstacleBody.Friction = 0.5f;

			this.ObstacleBody.Rotation = rotation * Constants.ObstacleRotationMultiplier;

			this.ObstacleBody.Position = new Vector2(xpos, ypos);

			this.ObstacleBody.CollisionCategories = Constants.ObstacleCollisionCategory;
			
			//We don't want player to be on top of start sign
			if (obstacleType == Enums.ObstacleType.Start)
				this.ObstacleBody.CollidesWith = Constants.StartCollidesWith;
			else
				this.ObstacleBody.CollidesWith = Constants.ObstacleCollidesWith;

			this.ObstacleType = obstacleType;

			this.Active = true;

			this.ObstacleBody.OnCollision += HandleCollision;

		}

		/// <summary>
		/// Draws the obstacle.
		/// </summary>
		/// <param name="spriteBatch">The sprite batch.</param>
		public virtual void Draw(SpriteBatch spriteBatch)
		{
			if (this.Active)
			{
				float obstacleScale;
				obstacleScale = this.Height / Constants.MeterInPixels;

				spriteBatch.Draw(
					this.ObstacleSprite,
					this.ObstacleBody.Position * Constants.MeterInPixels,
					null,
					Color.White,
					this.ObstacleBody.Rotation,
					this.Origin,
					obstacleScale,
					SpriteEffects.None,
					0f);
			}
		}

		/// <summary>
		/// Deletes the obstacle from the world.
		/// </summary>
		/// <param name="world">The world.</param>
		public void Delete(World world)
		{
			this.Active = false;
			if (world.BodyList.Contains(this.ObstacleBody))
				world.RemoveBody(this.ObstacleBody);
		}

		/// <summary>
		/// Handles the collision.
		/// </summary>
		/// <param name="a">The obstacle</param>
		/// <param name="b">The hitter</param>
		/// <param name="c">Contact type</param>
		/// <returns></returns>
		private bool HandleCollision(Fixture a, Fixture b, FarseerPhysics.Dynamics.Contacts.Contact c)
		{
			if (b.UserData is Character)
			{
				if (this.ObstacleType == Enums.ObstacleType.DeadlyObstacle)
				{
					var character = (Character)b.UserData;
					character.Kill();
				}
			}

			return true;
		}

	}
}
